package com.itsccn.quartzdemo.scheduler;

import java.util.Date;

import javax.annotation.PostConstruct;

import org.apache.log4j.Logger;
import org.quartz.DateBuilder;
import org.quartz.DateBuilder.IntervalUnit;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.SchedulerFactory;
import org.quartz.SchedulerMetaData;
import org.quartz.SimpleScheduleBuilder;
import org.quartz.SimpleTrigger;
import org.quartz.TriggerBuilder;
import org.quartz.impl.StdSchedulerFactory;
import org.springframework.stereotype.Component;

import com.itsccn.quartzdemo.Job.HelloJob;

public class SimpleTriggerExample {
	
	public void run() throws Exception {
		Logger log = Logger.getLogger(SimpleTriggerExample.class);

		log.info("------- Initializing -------------------");

		// 得到调度器实例的引用
		SchedulerFactory sf = new StdSchedulerFactory();
		Scheduler sched = sf.getScheduler();

		log.info("------- Initialization Complete --------");
		log.info("------- Scheduling Jobs ----------------");

		// jobs can be scheduled before sched.start() has been called

		// 任务开始时间的秒数是15的倍数
		Date startTime = DateBuilder.nextGivenSecondDate(null, 15);

		// job1开始时间的秒数是15的倍数
		JobDetail job = JobBuilder.newJob(HelloJob.class).withIdentity("job1", "group1").build();
		SimpleTrigger trigger = (SimpleTrigger) TriggerBuilder.newTrigger().withIdentity("trigger1", "group1")
				.startAt(startTime).build();
		// 调度任务
		Date ft = sched.scheduleJob(job, trigger);
		log.info(job.getKey() + " will run at: " + ft + " and repeat: " + trigger.getRepeatCount() + " times, every "
				+ trigger.getRepeatInterval() / 1000 + " seconds");

		// job2开始时间的秒数是15的倍数
		job = JobBuilder.newJob(HelloJob.class).withIdentity("job2", "group1").build();
		trigger = (SimpleTrigger) TriggerBuilder.newTrigger().withIdentity("trigger2", "group1").startAt(startTime)
				.build();
		ft = sched.scheduleJob(job, trigger);
		log.info(job.getKey() + " will run at: " + ft + " and repeat: " + trigger.getRepeatCount() + " times, every "
				+ trigger.getRepeatInterval() / 1000 + " seconds");

		// job3开始时间的秒数是15的倍数（运行一次，重复10次，共11次，每次运行间隔为10s）
		job = JobBuilder.newJob(HelloJob.class).withIdentity("job3", "group1").build();
		trigger = TriggerBuilder.newTrigger().withIdentity("trigger3", "group1").startAt(startTime)
				.withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(10).withRepeatCount(10))
				.build();
		ft = sched.scheduleJob(job, trigger);
		log.info(job.getKey() + " will run at: " + ft + " and repeat: " + trigger.getRepeatCount() + " times, every "
				+ trigger.getRepeatInterval() / 1000 + " seconds");

		// 相同的job3开始时间的秒数是15的倍数（运行一次，重复2次，共3次，每次运行间隔为10s）
		trigger = TriggerBuilder.newTrigger().withIdentity("trigger3", "group2").startAt(startTime)
				.withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(10).withRepeatCount(2))
				.forJob(job).build();
		ft = sched.scheduleJob(trigger);
		log.info(job.getKey() + " will [also] run at: " + ft + " and repeat: " + trigger.getRepeatCount()
				+ " times, every " + trigger.getRepeatInterval() / 1000 + " seconds");

		// job4开始时间的秒数是15的倍数（运行一次，重复5次，共6次，每次运行间隔为10s）
		job = JobBuilder.newJob(HelloJob.class).withIdentity("job4", "group1").build();
		trigger = TriggerBuilder.newTrigger().withIdentity("trigger4", "group1").startAt(startTime)
				.withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(10).withRepeatCount(5))
				.build();
		ft = sched.scheduleJob(job, trigger);
		log.info(job.getKey() + " will run at: " + ft + " and repeat: " + trigger.getRepeatCount() + " times, every "
				+ trigger.getRepeatInterval() / 1000 + " seconds");

		// job5会立即调度，运行时间在5分钟后
		job = JobBuilder.newJob(HelloJob.class).withIdentity("job5", "group1").build();
		trigger = (SimpleTrigger) TriggerBuilder.newTrigger().withIdentity("trigger5", "group1")
				.startAt(DateBuilder.futureDate(5, IntervalUnit.MINUTE)).build();
		ft = sched.scheduleJob(job, trigger);
		log.info(job.getKey() + " will run at: " + ft + " and repeat: " + trigger.getRepeatCount() + " times, every "
				+ trigger.getRepeatInterval() / 1000 + " seconds");

		// job6开始时间的秒数是15的倍数,并且每40秒会重复运行一次，无限重复
		job = JobBuilder.newJob(HelloJob.class).withIdentity("job6", "group1").build();
		trigger = TriggerBuilder.newTrigger().withIdentity("trigger6", "group1").startAt(startTime)
				.withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(40).repeatForever()).build();
		ft = sched.scheduleJob(job, trigger);
		log.info(job.getKey() + " will run at: " + ft + " and repeat: " + trigger.getRepeatCount() + " times, every "
				+ trigger.getRepeatInterval() / 1000 + " seconds");

		log.info("------- Starting Scheduler ----------------");

		// 所有的任务已加入调度器，但调度器未开始之前所有的任务都不会运行
		sched.start();
		log.info("------- Started Scheduler -----------------");
		// 调度器运行后任务仍然可以被调度

		// job7开始时间的秒数是15的倍数,并且每5分钟会重复运行一次，重复20次
		job = JobBuilder.newJob(HelloJob.class).withIdentity("job7", "group1").build();
		trigger = TriggerBuilder.newTrigger().withIdentity("trigger7", "group1").startAt(startTime)
				.withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInMinutes(5).withRepeatCount(20))
				.build();
		ft = sched.scheduleJob(job, trigger);
		log.info(job.getKey() + " will run at: " + ft + " and repeat: " + trigger.getRepeatCount() + " times, every "
				+ trigger.getRepeatInterval() / 1000 + " seconds");

		// job8可以直接运行，而不使用触发器
		job = JobBuilder.newJob(HelloJob.class).withIdentity("job8", "group1").storeDurably().build();
		sched.addJob(job, true);
		log.info("'Manually' triggering job8...");
		sched.triggerJob(JobKey.jobKey("job8", "group1"));

		log.info("------- Waiting 30 seconds... --------------");

		try {
			Thread.sleep(30L * 1000L);
		} catch (Exception e) {
			e.printStackTrace();
		}

		// job7可以重复调度，开始时间的秒数是15的倍数,并且每5分钟会重复运行一次，重复20次
		log.info("------- Rescheduling... --------------------");
		trigger = TriggerBuilder.newTrigger().withIdentity("trigger7", "group1").startAt(startTime)
				.withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInMinutes(5).withRepeatCount(20))
				.build();

		ft = sched.rescheduleJob(trigger.getKey(), trigger);
		log.info("job7 rescheduled to run at: " + ft);

		log.info("------- Waiting five minutes... ------------");
		try {
			// 等待5分钟
			Thread.sleep(300L * 1000L);
		} catch (Exception e) {
			e.printStackTrace();
		}

		log.info("------- Shutting Down ---------------------");

		sched.shutdown(true);

		log.info("------- Shutdown Complete -----------------");

		// 显示调度器的状态
		SchedulerMetaData metaData = sched.getMetaData();
		log.info("Executed " + metaData.getNumberOfJobsExecuted() + " jobs.");
	}
}
